﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection;
using System.Collections;

namespace CP.Utility
{
    public static class ExtensionMethods
    {
        // Deep clone
        public static T DeepClone<T>(this T toBeCloned)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, toBeCloned);
                stream.Position = 0;
                return (T)formatter.Deserialize(stream);
            }
        }

        public static object CopyObject(this object input)
        {
            if (input != null)
            {
                object result = Activator.CreateInstance(input.GetType());

                var properties = input.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
                foreach (var property in properties)
                {
                    if (property.PropertyType.GetInterface("IList", false) == null)
                    { 
                        property.SetValue(result, property.GetValue(input, null), null);
                    }
                    else
                    {
                        IList listObject = (IList)property.GetValue(input, null);
                        if (listObject != null)
                        {
                            foreach (object item in ((IList)property.GetValue(input, null)))
                            {
                                listObject.Add(item.CopyObject());
                            }
                        }
                    }
                }
                return result;
            }
            else
            {
                return null;
            }
        }
    }
}
